import { DatabaseOperations, DatabaseOperationsFactory } from '../utils/database-operations.js';
import { BusinessException } from '../types/exceptions.js';
import { Pool as MySQLPool } from 'mysql2/promise';
import { Pool as PgPool } from 'pg';

/**
 * 服务基类
 * @description 提供通用的服务层操作，减少重复代码
 */
export abstract class BaseService<
  T extends Record<string, unknown>,
  CreateDto extends Record<string, unknown>,
  UpdateDto extends Record<string, unknown>,
  QueryDto extends Record<string, unknown>,
  Operations extends DatabaseOperations<T>,
> {
  protected dbOperations: Operations | null = null;

  constructor(
    private MySQLOperationsClass: new (pool: MySQLPool) => Operations,
    private PostgreSQLOperationsClass: new (pool: PgPool) => Operations
  ) {}

  /**
   * 获取数据库操作实例
   * @returns 数据库操作实例
   */
  protected getDbOperations(): Operations {
    if (!this.dbOperations) {
      this.dbOperations = DatabaseOperationsFactory.create<Operations>(
        this.MySQLOperationsClass,
        this.PostgreSQLOperationsClass
      );
    }
    return this.dbOperations;
  }

  /**
   * 创建记录
   * @param data 创建数据
   * @returns 创建的记录ID
   */
  async create(data: CreateDto): Promise<number> {
    return this.getDbOperations().create(data as Omit<T, 'id'>);
  }

  /**
   * 根据ID获取记录
   * @param id 记录ID
   * @returns 记录数据或null
   */
  async getById(id: number): Promise<T | null> {
    return this.getDbOperations().getById(id);
  }

  /**
   * 更新记录
   * @param id 记录ID
   * @param data 更新数据
   * @returns 是否更新成功
   */
  async update(id: number, data: UpdateDto): Promise<boolean> {
    const result = await this.getDbOperations().update(id, data as Partial<T>);
    if (!result) {
      throw new BusinessException('记录不存在或已被删除');
    }
    return result;
  }

  /**
   * 删除记录
   * @param id 记录ID
   * @returns 是否删除成功
   */
  async delete(id: number): Promise<boolean> {
    const result = await this.getDbOperations().delete(id);
    if (!result) {
      throw new BusinessException('记录不存在');
    }
    return result;
  }

  /**
   * 获取记录列表
   * @param page 页码，默认为1
   * @param pageSize 每页数量，默认为10
   * @param query 查询条件
   * @returns 分页的记录列表
   */
  async list(
    page: number = 1,
    pageSize: number = 10,
    query: QueryDto = {} as QueryDto
  ): Promise<{ total: number; list: T[]; page: number; pageSize: number }> {
    return this.getDbOperations().list(page, pageSize, query as Partial<T>);
  }

  /**
   * 验证记录是否存在
   * @param id 记录ID
   * @param errorMessage 错误消息
   * @returns 记录数据
   */
  protected async validateExists(id: number, errorMessage: string = '记录不存在'): Promise<T> {
    const record = await this.getById(id);
    if (!record) {
      throw new BusinessException(errorMessage);
    }
    return record;
  }

  /**
   * 批量删除记录（如果数据库操作支持）
   * @param ids 记录ID数组
   * @returns 是否删除成功
   */
  protected async batchDelete(ids: number[]): Promise<boolean> {
    const operations = this.getDbOperations() as Operations & {
      batchDelete?: (ids: number[]) => Promise<boolean>;
    };
    if (typeof operations.batchDelete === 'function') {
      return operations.batchDelete(ids);
    }

    // 如果不支持批量删除，则逐个删除
    const results = await Promise.all(ids.map(id => this.delete(id)));
    return results.every(result => result);
  }
}
